package fr.asip.cps3.exemple;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import fr.asip.cps3.exemple.controleurs.ApplicationControleur;
import fr.asip.cps3.exemple.modele.Application;
import fr.asip.cps3.exemple.modele.MenuApplication;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionLibrairie;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionProgrammeExemple;

/**
 * Classe de démarrage du programme d'exemple
 *
 */
public class Lancement {
	
	/**
	 * Le loggeur
	 */
	 private static Logger log = Logger.getLogger(Lancement.class);	
	
	/**
	 * Méthode main
	 * @param args
	 */
	public static void main(String args[]) {

		try {
		
			// L'application
			Application application = null;
			
			// Le booléen qui à true provoque l'arrêt du programme 
			boolean terminerProgramme = false;
	
			// Chargement de la configuration Log4j
			File log4jProps = null;
			URL url = Lancement.class.getResource("/log4j.properties");
			if(url != null) {
				log4jProps = new File(url.getFile());
			}
			if(log4jProps != null && log4jProps.exists())
				try {
					PropertyConfigurator.configure(log4jProps.toURL());
				} catch (MalformedURLException e1) {
					System.out.println("Le chemin du fichier de configuration Log4j est invalide");
					terminerProgramme = true;
				}
			System.out.println("Configuration de Log4j : OK");			
			
			if(!terminerProgramme) {
				
				// Initialisation de l'application
				application  = new Application();
				if(application != null && application.getLibrairieP11() == null) {
					
					 // Si la librairie par défaut ne s'est pas chargé, on propose à l'utilisateur de sélectionner une librairie
					 // depuis le système de fichiers
					 while(application.getLibrairieP11() == null && !terminerProgramme) {
						
						final JFrame fenetre = new JFrame();

						// Attribution du look and feel
						String lookAndFeel = UIManager.getSystemLookAndFeelClassName();
						try {
							UIManager.setLookAndFeel(lookAndFeel);
						} catch (Exception e) {
							log.error("Une erreur est survenue lors de l'attribution du look and feel de l'application");							
						}
						
						
						fenetre.addWindowListener(new java.awt.event.WindowAdapter() {
							   public void windowClosing(java.awt.event.WindowEvent e) {
									if(fenetre != null) {
										fenetre.setVisible(false);
										fenetre.dispose();
									}
							   }
							});
						
						// Avertissement du chargement infructeux de la librairie, et proposition de la chargement explicite
						Object[] options = {"Charger une librairie...", "Quitter"};
						int reponse = JOptionPane.showOptionDialog(fenetre,
								"La librairie "+application.getCheminLibrairieP11()+" est inaccessible ou invalide!\nVous devez spécifier une librairie valide",
								"Erreur de lancement",
							    JOptionPane.YES_NO_OPTION,
							    JOptionPane.ERROR_MESSAGE,
							    null,
							    options,
							    options[0]);
		
						// L'utilisateur a choisi de charger une librairie
						if(reponse == 0) {
							
							// Chargement explicite de la librairie
							JFileChooser fc = new JFileChooser();
							fc.setAcceptAllFileFilterUsed(false);
							fc.setFileFilter(Application.getFiltreLibrairie());
							fc.setDialogTitle("Sélectionnez une librairie");
							int valeurRetour = fc.showOpenDialog(fenetre);
					        if (valeurRetour == JFileChooser.APPROVE_OPTION) {
					            File fichier = fc.getSelectedFile();
					            if(fichier != null)
					            	application = new Application(fichier.getAbsolutePath());
					        } else
					        	terminerProgramme = true;
						}
						
						// L'utilisateur à choisi de quitter le programme
						else
							terminerProgramme = true;
						
						if(fenetre != null) {
							fenetre.setVisible(false);
							fenetre.dispose();
						}
			        }
				}
			}
				
			// S'il faut terminer le programme, on sort
			if(terminerProgramme || application == null) {
				log.debug("Sortie du programme");
	        	System.exit(0);
			}
			
			// Sinon on affiche la fenêtre principale
			ApplicationControleur controleur = new ApplicationControleur(application);
			controleur.afficheFenetrePrincipale();
			if(application != null && application.getTraitementsSpecifiques() == null) {
				application.getMenu().setItemMenuNonActif(MenuApplication.TRAITEMENTSSPECIFIQUES);
				application.notifieException(new ExceptionLibrairie(ExceptionProgrammeExemple.TYPE_LIBRAIRIE_EXCEPTION_CHARGEMENT_LIB_TS, "Une erreur est survenue au chargement de la librairie des traitements spécifiques.\nLe module Traitements spécifiques est inutilisable."));
			}

		} catch (Throwable t) {
			
			final JFrame fenetre = new JFrame();
			
			// Attribution du look and feel
			String lookAndFeel = UIManager.getSystemLookAndFeelClassName();
			try {
				UIManager.setLookAndFeel(lookAndFeel);
			} catch (Throwable twb) {
				log.error("Une erreur est survenue lors de l'attribution du look and feel de l'application");
			}				 
			
			fenetre.addWindowListener(new java.awt.event.WindowAdapter() {
				   public void windowClosing(java.awt.event.WindowEvent e) {
						if(fenetre != null) {
							fenetre.setVisible(false);
							fenetre.dispose();
						}
						log.debug("Sortie du programme");
						System.exit(0);
				   }
				});
			
			// Avertissement concernant l'erreur de lancement du programme d'exemple
			JOptionPane.showMessageDialog(fenetre,"Une erreur est survenue au lancement du programme d'exemple","Erreur de lancement",JOptionPane.ERROR_MESSAGE);
			
			log.debug("Sortie du programme");
			if(fenetre != null)
				fenetre.dispose();
			System.exit(0);
			
		}
	}
}